<!--
 * @Author: Liuxin 2849181826@qq.com
 * @Date: 2025-04-08 11:00:21
 * @LastEditors: Liuxin 2849181826@qq.com
 * @LastEditTime: 2025-04-27 16:55:43
 * @FilePath: \browser\electron-vite-vue\src\views\Home.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<script setup lang="ts">
import { ref, reactive, onMounted, computed } from "vue"
import type { FormInstance, FormRules } from "element-plus"
import { ElMessage, ElMessageBox } from "element-plus"
import { Close, Loading, Refresh, Setting, Plus, Delete, Link } from "@element-plus/icons-vue"
import { useUserStore } from "../store/modules/user"
import { v4 as uuidv4 } from "uuid"
import { createDevice, getDeviceList, deleteDevice } from "../api/web/index"
import { checkAndRedirect } from "../utils/auth"
import { nextTick } from "vue"
import FacebookImage from "../assets/platformIcon/Facebook.png"
import ThreadsImageImage from "../assets/platformIcon/threads-fill.png"
import TikTokImageImage from "../assets/platformIcon/tiktoklogo_tiktok.png"
type ImageUrlKeys = "Threads" | "Facebook" | "TikTok"
const imageUrl: {
  Threads: string
  Facebook: string
  TikTok: string
} = {
  Threads: ThreadsImageImage,
  Facebook: FacebookImage,
  TikTok: TikTokImageImage,
}
const userStore = useUserStore()
const userInfo = ref(userStore.getUserInfo)
// 解决 window.automation 的类型问题
declare global {
  interface Window {
    automation: {
      start: (data: any) => Promise<{ success: boolean }>
      stop: () => Promise<{ success: boolean; isRunning: boolean }>
    }
  }
}

// 定义账号列表的类型
export interface DeviceList {
  id: string
  deviceId: string
  hostId: null | string
  host: object | null
  groupId: string | null
  groupName: string | null
  status: number
  statusName: string
  enabled: boolean
  deviceTypeName: string
  deptId: string | null
  deptName: string | null
  tenantId: string | null
  tenantName: string
  platformAccounts: any[] // 如果你有更明确的结构，也可以替换为具体类型
  createTime: number
  platformName: string
  taskId: string
}

// 自动化服务状态
const isRunning = ref(JSON.parse(localStorage.getItem("isRunning") as string))

// 当前用户名
const username = ref("")

// 账号列表数据
const deviceList = ref<DeviceList[]>([])

// 选中的行数据
const currentRow = ref<DeviceList | null>(null)
// 多选选中的行
const multipleSelection = ref<DeviceList[]>(JSON.parse(localStorage.getItem("selectedRows") as string) || [])
console.log("multipleSelection==>", multipleSelection)
// 控制modal显示状态
const newWindowModalVisible = ref(false)
const bindAccountModalVisible = ref(false)
const fingerprintApiModalVisible = ref(false)

// 新增窗口表单
const windowForm = reactive<{
  windows: { id: string }[]
}>({
  windows: [{ id: "" }],
})

// 绑定账号表单
const platformForm = reactive({
  platformName: "",
})

// 指纹API表单
const apiForm = reactive({
  apiUrl: "",
})

// 新增窗口表单的校验规则
const windowFormRules = reactive<FormRules>({
  windows: [
    {
      validator: (_rule: any, value: any, callback: any) => {
        if (value.some((item: any) => !item.id)) {
          callback(new Error("窗口ID不能为空"))
        } else {
          callback()
        }
      },
      trigger: "blur",
    },
  ],
})

// 指纹API表单的校验规则
const apiFormRules = reactive<FormRules>({
  apiUrl: [
    { required: true, message: "请输入指纹接口地址", trigger: "blur" },
    {
      pattern: /^https?:\/\/.+$/,
      message: "请输入正确格式的指纹接口地址，例如: http://xxxxxxx:000000",
      trigger: "blur",
    },
  ],
})

// 绑定账号表单的校验规则
const platformFormRules = reactive<FormRules>({
  platformName: [{ required: true, message: "请选择业务平台", trigger: "change" }],
})
// ref el-table 实例
const tableRef = ref()
// 表单引用
const windowFormRef = ref<FormInstance>()
const platformFormRef = ref<FormInstance>()
const apiFormRef = ref<FormInstance>()
function setSelectedRows() {
  if (!tableRef.value) return
  multipleSelection.value.forEach((item) => {
    const matchedRow = deviceList.value.find((row) => row.id === item.id)
    if (matchedRow) {
      tableRef.value.toggleRowSelection(matchedRow, true)
    }
  })
}
// 添加窗口输入框
const addWindowInput = () => {
  windowForm.windows.push({ id: "" })
}

// 移除窗口输入框
const removeWindowInput = (index: number) => {
  if (windowForm.windows.length > 1) {
    windowForm.windows.splice(index, 1)
  }
}

// 平台选项
const platformOptions = [
  { value: "TikTok", label: "TikTok" },
  // { value: "Instagram", label: "Instagram" },
  { value: "Threads", label: "Threads" },
  { value: "Facebook", label: "Facebook" },
  // { value: "Twitter", label: "Twitter" },
]

// 确认添加窗口
const confirmAddWindow = async () => {
  if (!windowFormRef.value) return

  await windowFormRef.value.validate((valid) => {
    if (valid) {
      const existingIds = new Set(deviceList.value.map((acc) => acc.id))

      const newValidWindows = windowForm.windows.map((win) => win.id.trim()).filter((id) => id && !existingIds.has(id))

      if (newValidWindows.length === 0) {
        const duplicateIds = windowForm.windows.map((win) => win.id.trim()).filter((id) => existingIds.has(id))

        if (duplicateIds.length > 0) {
          ElMessage.warning(`以下窗口ID已存在，未添加：${duplicateIds.join(", ")}`)
        } else {
          ElMessage.warning(`窗口id为空，不能添加`)
        }
        return
      }
      console.log("platformForm.platformName===>", platformForm.platformName)
      // 添加去重后的窗口ID
      newValidWindows.forEach(async (id) => {
        if (deviceList.value.findIndex((acc) => acc.id === id) === -1) {
          console.log("userInfo===>", userInfo)
          // 创建设备
          try {
            const deviceRes = await createDevice(
              {
                deviceId: id,
                deviceTypeName: "browser",
              },
              {
                Authorization: useUserStore().accessToken,
              }
            )
            console.log("deviceRes====>", deviceRes)
            if (!deviceRes.data) {
              ElMessage.error(`${deviceRes.msg}`)
              return
            }
          } catch (error) {
            console.error("创建设备失败:", error)
            ElMessage.error("创建设备失败")
            return error
          }
          ElMessage.success("新增窗口成功")
          await getDeviceListFunc()
        } else {
          ElMessage.warning(`窗口ID ${id} 已存在，未添加`)
        }
      })

      // 重置表单
      newWindowModalVisible.value = false
      windowForm.windows = [{ id: "" }]
    }
  })
}

// 绑定账号状态
const isBinding = ref(false)

// 确认绑定账号
const confirmBindAccount = async () => {
  if (!platformFormRef.value) return

  await platformFormRef.value.validate(async (valid) => {
    if (valid) {
      if (multipleSelection.value.length === 0) {
        ElMessage.warning("请先选择窗口")
        return
      }
      // 检查是否有已绑定平台的窗口--一个窗口只能绑定一个窗口
      // const hasBoundPlatform = multipleSelection.value.some((account) => account.platformAccounts.length > 0)
      // if (hasBoundPlatform) {
      //   ElMessage.warning("有窗口已绑定平台账号，请先解绑后再绑定。目前仅支持一个窗口一个账号")
      //   return
      // }
      try {
        isBinding.value = true
        // 调用绑定账号接口
        const result = await window.automation.start(
          JSON.stringify({
            action: "bindAccount",
            createTime: new Date().toLocaleString("zh-CN", { timeZone: "Asia/Shanghai" }),
            data: multipleSelection.value.map((v) => {
              // 不再直接修改 v.platformName，而是在传递时设置
              return {
                ...v,
                platformName: platformForm.platformName,
              }
            }),
            adsApiUrl: localStorage.getItem("fingerprintApiUrl") || "",
            deviceIdList: multipleSelection.value.map((v) => v.deviceId),
          })
        )

        if (result.success) {
          ElMessage.success("开始绑定账号")
        }
      } catch (error) {
        console.error("绑定账号失败:", error)
        ElMessage.error("绑定账号失败")
        isBinding.value = false
      }
    }
  })
}

// 停止绑定账号
const stopBinding = async () => {
  try {
    console.log("执行停止绑定账号，准备关闭所有浏览器窗口...")

    // 设置状态为正在处理中
    isBinding.value = true

    const loadingMessage = ElMessage({
      message: "正在关闭浏览器窗口并停止绑定...",
      type: "info",
      duration: 0,
      showClose: true,
    })

    // 先强制等待一段时间，确保数据已经被保存
    await new Promise((resolve) => setTimeout(resolve, 1000))

    // 尝试停止自动化服务
    const result = await window.automation.stop()

    // 额外等待时间确保窗口关闭 - 绑定账号窗口可能需要更长时间关闭
    await new Promise((resolve) => setTimeout(resolve, 8000))

    loadingMessage.close()

    if (result.success) {
      isBinding.value = false
      ElMessage.success("已停止绑定账号并关闭所有浏览器窗口")

      // 延迟刷新列表，给窗口充分时间关闭
      setTimeout(() => {
        getDeviceListFunc()
      }, 2000)
    } else {
      // 如果首次尝试失败，再试一次
      ElMessage.warning("首次停止尝试未成功，正在重试...")

      // 等待一段时间后重试
      await new Promise((resolve) => setTimeout(resolve, 2000))
      const retryResult = await window.automation.stop()

      // 再次等待，确保窗口关闭
      await new Promise((resolve) => setTimeout(resolve, 5000))

      if (retryResult.success) {
        isBinding.value = false
        ElMessage.success("已停止绑定账号")

        // 重新加载列表
        setTimeout(() => {
          getDeviceListFunc()
        }, 2000)
      } else {
        // 第二次失败，尝试最后一次，但使用ipcRenderer直接触发强制刷新
        try {
          ElMessage.warning("尝试强制清理资源...")

          // 如果有 ipcRenderer 可用，尝试重新加载主窗口
          window.ipcRenderer.send("win-reload")

          // 等待重新加载
          await new Promise((resolve) => setTimeout(resolve, 3000))

          isBinding.value = false
        } catch (reloadError) {
          console.error("重新加载窗口失败:", reloadError)
          ElMessage.error("无法完全停止服务，请重启应用")

          // 无论如何都更新状态
          isBinding.value = false

          // 刷新页面以重置状态
          setTimeout(() => {
            window.location.reload()
          }, 3000)
        }
      }
    }
  } catch (error) {
    console.error("停止绑定失败:", error)
    ElMessage.error("停止绑定失败，正在尝试恢复...")

    // 尝试通过刷新页面来恢复
    setTimeout(() => {
      try {
        // 先尝试使用 ipcRenderer 重新加载
        window.ipcRenderer.send("win-reload")
      } catch (reloadError) {
        console.error("重新加载窗口失败，将刷新页面:", reloadError)
        // 如果失败，则刷新页面
        window.location.reload()
      } finally {
        // 无论如何，更新UI状态
        isBinding.value = false
      }
    }, 2000)
  }
}

// 确认设置指纹API
const confirmSetApi = async () => {
  if (!apiFormRef.value) return

  await apiFormRef.value.validate((valid) => {
    if (valid) {
      // 在实际应用中，这里应该保存API地址
      ElMessage.success(`指纹接口地址设置成功: ${apiForm.apiUrl}`)
      localStorage.setItem("fingerprintApiUrl", apiForm.apiUrl)
      // 关闭模态框并重置表单
      fingerprintApiModalVisible.value = false
    }
  })
}

// 处理表格行点击
const handleRowClick = (row: DeviceList) => {
  currentRow.value = row
}

// 处理表格多选变化
const handleSelectionChange = (selection: DeviceList[]) => {
  multipleSelection.value = selection
  // 存一份放在本地
  localStorage.setItem("selectedRows", JSON.stringify(selection))
}

// 删除窗口
const deleteWindow = (row: DeviceList) => {
  ElMessageBox.confirm(`确定要删除窗口 ${row.deviceId} 吗？`, "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(async () => {
      const index = deviceList.value.findIndex((item) => item.id === row.id)
      if (index !== -1) {
        const deleteDeviceRes = await deleteDevice(
          { id: row.id },
          {
            Authorization: useUserStore().accessToken,
          }
        )
        console.log("deleteDeviceRes===>", deleteDeviceRes)
        deviceList.value.splice(index, 1)
        ElMessage.success("删除成功")
        await getDeviceListFunc()
      }
    })
    .catch(() => {
      // 取消删除
    })
}

// 开始运行
const startRun = async () => {
  if (multipleSelection.value.length === 0 && !isRunning.value) {
    ElMessage.warning("请先选择至少一个窗口")
    return
  }

  // 检查是否有已绑定平台的窗口
  const hasBoundPlatform = multipleSelection.value.every((account) => account.platformAccounts.length > 0 && account.host && account.platformAccounts.every((acc) => acc.platformName))

  if (!hasBoundPlatform) {
    ElMessage.warning("有窗口未绑定平台、账号、主播。请先在后台绑定后再启动自动化服务。")
    return
  }
  // 判断adsAPi地址是否存在
  if (!hasFingerprintApi.value) {
    ElMessage.warning("请先设置指纹接口地址")
    return
  }
  if (!isRunning.value) {
    try {
      // 传递选中的窗口数据到主进程
      const result = await window.automation.start(
        // 构建运行的账号数据
        JSON.stringify({
          action: "runTask",
          createTime: new Date().toLocaleString("zh-CN", { timeZone: "Asia/Shanghai" }),
          data: multipleSelection.value,
          adsApiUrl: localStorage.getItem("fingerprintApiUrl") || "",
          deviceIdList: multipleSelection.value.map((v) => v.deviceId),
        })
      )
      isRunning.value = result.success
      localStorage.setItem("isRunning", JSON.stringify(isRunning.value))
      if (result.success) {
        ElMessage.success("自动化服务已启动")
      }
    } catch (error) {
      console.error("启动自动化服务失败:", error)
      ElMessage.error("启动自动化服务失败")
    }
  } else {
    ElMessageBox.confirm("确定要停止自动化服务吗？", "提示", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning",
    })
      .then(async () => {
        try {
          const loadingMessage = ElMessage({
            message: "正在关闭浏览器窗口并停止服务...",
            type: "info",
            duration: 0,
            showClose: true,
          })

          // 尝试停止自动化服务
          const result = await window.automation.stop()

          // 即使成功，也额外等待一会儿确保窗口都被关闭
          await new Promise((resolve) => setTimeout(resolve, 2000))

          loadingMessage.close()

          if (result.success) {
            isRunning.value = false
            localStorage.setItem("isRunning", JSON.stringify(isRunning.value))
            ElMessage.success("自动化服务已停止")
          } else {
            // 如果首次尝试失败，再试一次
            ElMessage.warning("首次停止尝试未成功，正在重试...")

            // 等待一段时间后重试
            await new Promise((resolve) => setTimeout(resolve, 2000))
            const retryResult = await window.automation.stop()

            isRunning.value = !retryResult.success
            localStorage.setItem("isRunning", JSON.stringify(isRunning.value))
            if (retryResult.success) {
              ElMessage.success("自动化服务已停止")
            } else {
              ElMessage.error("无法完全停止服务，请重启应用")
            }
          }
        } catch (error) {
          console.error("停止自动化服务失败:", error)
          ElMessage.error("停止自动化服务失败，请重启应用")
          // 无论如何，更新UI状态
          isRunning.value = false
          localStorage.setItem("isRunning", JSON.stringify(isRunning.value))
        }
      })
      .catch(() => {
        // 用户取消操作
      })
  }
}

// 计算属性：是否有指纹API地址
const hasFingerprintApi = computed(() => {
  return /^https?:\/\/.+$/.test(apiForm.apiUrl)
})

// 计算属性：是否有选中的窗口
const hasSelectedWindows = computed(() => {
  return multipleSelection.value.length > 0
})

async function getDeviceListFunc() {
  // 获取列表数据
  const deviceListRes = await getDeviceList(
    {
      pageNo: 1,
      pageSize: 100,
      deviceTypeName: "browser",
    },
    {
      Authorization: useUserStore().accessToken,
    }
  )
  console.log("deviceListRes===>", deviceListRes)
  const deviceListResult = deviceListRes.data?.list || []
  console.log("deviceListResult===>", deviceListResult)
  deviceList.value = deviceListResult.map((device: any) => {
    return {
      ...device,
      platformName: "",
      taskId: uuidv4(),
    }
  })
  console.log("deviceList===>new", deviceList.value)
  ElMessage.success("获取列表数据成功")
}

// 页面加载时检查登录状态
onMounted(async () => {
  console.log("Home页面加载，检查登录状态")

  // 使用checkAndRedirect函数验证登录状态 - 未登录状态下会自动跳转
  if (!checkAndRedirect()) {
    console.log("未登录状态，页面将重定向")
    return
  }

  console.log("已登录状态，继续加载页面")

  // 页面正常初始化
  try {
    // 监听子进程
    window.ipcRenderer.on("bind-account-done", (_event, data) => {
      console.log("bind-account-done", data)
      // 调用停止绑定方法
      ElMessage.success("已完成业务账号绑定")
      stopBinding()
      getDeviceListFunc()
    })

    window.ipcRenderer.on("run-task-done", async (_event, data) => {
      console.log("run-task-done", data)
      // 调用停止绑定方法
      ElMessage.success("已完成业务任务")
      const result = await window.automation.stop()
      console.log("result==>", result)
      isRunning.value = !result.success
      localStorage.setItem("isRunning", JSON.stringify(isRunning.value))
      if (result.success) {
        ElMessage.success("自动化服务已停止")
      }
    })

    window.ipcRenderer.on("send-node-error", async (_event, data) => {
      console.log("send-node-error", data.payload)
      // 调用停止绑定方法
      ElMessage.error(data.payload)
    })

    if (localStorage.getItem("fingerprintApiUrl")) {
      apiForm.apiUrl = localStorage.getItem("fingerprintApiUrl") || ""
    }

    const urlParams = new URLSearchParams(window.location.search)
    username.value = urlParams.get("username") || "用户"

    // 获取设备列表
    await getDeviceListFunc()
  } catch (error) {
    console.error("页面初始化失败:", error)
    // 如果是401错误，checkAndRedirect已经处理了重定向
  }
  nextTick(() => {
    setSelectedRows()
  })
})
</script>

<template>
  <div class="app-frame">
    <div class="app-container">
      <div class="app-content">
        <div class="header">
          <div class="user-info">
            <h2>Hi~ <span class="emoji">🌞</span></h2>
          </div>
          <div class="action-buttons">
            <!-- 刷新按钮 -->
            <el-button @click="getDeviceListFunc" :disabled="isRunning" :icon="Refresh">刷新列表</el-button>
            <el-button @click="fingerprintApiModalVisible = true" :disabled="isRunning" :icon="Setting">指纹接口地址</el-button>
            <el-button @click="newWindowModalVisible = true" :disabled="!hasFingerprintApi || isRunning" :title="!hasFingerprintApi ? '请先填写指纹接口地址' : ''" :icon="Plus"> 新增窗口 </el-button>
            <el-button
              type="primary"
              @click="bindAccountModalVisible = true"
              :disabled="!hasSelectedWindows || !hasFingerprintApi || isRunning"
              :title="!hasFingerprintApi || !hasSelectedWindows ? '请先选择窗口' : ''"
              :icon="Link"
            >
              绑定账号
            </el-button>
          </div>
        </div>

        <div class="table-container">
          <el-table
            ref="tableRef"
            :data="deviceList"
            :selection="multipleSelection"
            highlight-current-row
            @current-change="handleRowClick"
            @selection-change="handleSelectionChange"
            style="width: 100%"
            v-if="deviceList.length > 0"
            :disabled="isRunning"
            border
            stripe
            class="data-table"
          >
            <el-table-column type="selection" width="55" />
            <el-table-column prop="deviceId" fixed label="窗口ID" width="150" />
            <el-table-column prop="host" label="人设" width="120">
              <template #default="{ row }">
                <div class="account-item" v-if="row?.host?.name">
                  {{ row?.host?.name }}
                </div>
                <span v-else>-</span>
              </template>
            </el-table-column>
            <el-table-column prop="platformName" label="业务平台" width="170">
              <template #default="{ row }">
                <template v-if="row.platformAccounts && row.platformAccounts.length">
                  <div v-for="(acc, idx) in row.platformAccounts" :key="idx" class="platform-item">
                    <div class="platform-item-image">
                      <el-image style="width: 20px; height: 20px; border-radius: 50%; margin-right: 8px" :src="imageUrl[acc.platformName as ImageUrlKeys]" fit="cover" />
                      {{ acc.platformName }}
                    </div>
                    <el-divider v-if="idx < row.platformAccounts.length - 1" direction="horizontal" />
                  </div>
                </template>
                <template v-else>{{ row.platformName || "-" }}</template>
              </template>
            </el-table-column>
            <el-table-column prop="nickName" label="昵称" min-width="120">
              <template #default="{ row }">
                <template v-if="row.platformAccounts && row.platformAccounts.length">
                  <div v-for="(acc, idx) in row.platformAccounts" :key="idx" class="platform-item">
                    <div class="account-item">{{ acc.nickName || "-" }}</div>
                    <el-divider v-if="idx < row.platformAccounts.length - 1" direction="horizontal" />
                  </div>
                </template>
                <template v-else>{{ row.nickName || "-" }}</template>
              </template>
            </el-table-column>
            <el-table-column prop="platformAccount" label="业务账号" min-width="120">
              <template #default="{ row }">
                <template v-if="row.platformAccounts && row.platformAccounts.length">
                  <div v-for="(acc, idx) in row.platformAccounts" :key="idx" class="platform-item">
                    <div class="account-item">{{ acc.platformAccount || "-" }}</div>
                    <el-divider v-if="idx < row.platformAccounts.length - 1" direction="horizontal" />
                  </div>
                </template>
                <template v-else>{{ row.platformAccount || "-" }}</template>
              </template>
            </el-table-column>
            <el-table-column label="操作" width="120" align="center">
              <template #default="scope">
                <el-button type="danger" size="small" @click="deleteWindow(scope.row)" :icon="Delete"> 删除 </el-button>
              </template>
            </el-table-column>
          </el-table>

          <div class="empty-container" v-else>
            <el-empty description="暂无窗口数据" />
          </div>
        </div>

        <div class="action-container">
          <el-button :type="isRunning ? 'danger' : 'primary'" size="large" @click="startRun" :disabled="!hasSelectedWindows" class="run-button">
            {{ isRunning ? "停止运行" : "开始运行" }}
          </el-button>
        </div>
      </div>
    </div>

    <!-- 新增窗口弹窗 -->
    <el-dialog v-model="newWindowModalVisible" title="创建新窗口" width="500px" destroy-on-close>
      <el-form :model="windowForm" ref="windowFormRef" :rules="windowFormRules" label-width="80px">
        <div v-for="(window, index) in windowForm.windows" :key="index" class="window-form-item">
          <el-form-item :label="index === 0 ? '窗口ID' : ''" :prop="`windows.${index}.id`">
            <div class="window-input-group">
              <el-input v-model="window.id" placeholder="例如: kqqkkkb" />
              <el-button v-if="index > 0" circle type="danger" @click="removeWindowInput(index)" :icon="Close" size="small" />
            </div>
          </el-form-item>
        </div>
        <el-button type="default" @click="addWindowInput" class="add-window-btn"> <span>+</span> 添加更多窗口 </el-button>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="newWindowModalVisible = false">取消</el-button>
          <el-button type="primary" @click="confirmAddWindow">确认</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 绑定账号弹窗 -->
    <el-dialog v-model="bindAccountModalVisible" title="绑定业务账号" width="500px">
      <el-form :model="platformForm" ref="platformFormRef" :rules="platformFormRules" label-width="100px">
        <el-form-item label="业务平台" prop="platformName">
          <el-select v-model="platformForm.platformName" placeholder="请选择业务平台" style="width: 100%">
            <el-option v-for="item in platformOptions" :key="item.value" :label="item.label" :value="item.value">
              <div style="display: flex; align-items: center">
                <el-image style="width: 20px; height: 20px; border-radius: 50%; margin-right: 8px" :src="imageUrl[item.value as ImageUrlKeys]" fit="cover" />
                <div>{{ item.value }}</div>
              </div>
            </el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="bindAccountModalVisible = false">取消</el-button>
          <el-button type="primary" @click="confirmBindAccount" :loading="isBinding" :disabled="isBinding">
            {{ isBinding ? "绑定中" : "开始绑定" }}
          </el-button>
          <el-button type="danger" @click="stopBinding" :disabled="!isBinding"> 停止绑定 </el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 指纹接口地址弹窗 -->
    <el-dialog v-model="fingerprintApiModalVisible" title="设置指纹接口地址" width="500px">
      <el-form :model="apiForm" ref="apiFormRef" :rules="apiFormRules" label-width="100px">
        <el-form-item label="接口地址" prop="apiUrl">
          <el-input v-model="apiForm.apiUrl" placeholder="如: http://xxxxxxxx:000000" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="fingerprintApiModalVisible = false">取消</el-button>
          <el-button type="primary" @click="confirmSetApi">确认</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 全局运行中蒙层 -->
    <div class="global-overlay" v-if="isRunning">
      <div class="overlay-content">
        <el-icon class="loading-icon"><Loading /></el-icon>
        <div class="loading-text">自动化服务运行中...</div>
        <div class="stop-button-container">
          <el-button type="danger" size="large" @click="startRun">停止运行</el-button>
        </div>
      </div>
    </div>
  </div>
</template>

<style lang="less" scoped>
.app-frame {
  width: 100%;
  height: calc(100vh - 80px);
  display: flex;
  flex-direction: column;
  background-color: #f5f7fa;
}

.app-container {
  flex: 1;
  display: flex;
  flex-direction: column;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
  background-color: white;
}

.app-content {
  flex: 1;
  padding: 24px;
  overflow: auto;
  position: relative;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;
  padding-bottom: 16px;
  border-bottom: 1px solid #ebeef5;
}

.user-info {
  font-size: 18px;
  color: #303133;
  h2 {
    margin: 0;
    font-weight: 600;
  }
  .emoji {
    font-size: 22px;
  }
}

.action-buttons {
  display: flex;
  gap: 12px;
}

.table-container {
  width: 100%;
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
  padding: 8px;
  margin-bottom: 70px;
}

.data-table {
  margin-top: 8px;
  :deep(.el-table__header) {
    font-weight: 600;
  }
  :deep(.el-table__cell) {
    vertical-align: middle;
  }
}

.action-container {
  position: fixed;
  bottom: 40px;
  left: 0;
  width: 100%;
  display: flex;
  justify-content: center;
  z-index: 100;
}

.run-button {
  padding: 12px 36px;
  font-size: 16px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.window-form-item {
  margin-bottom: 10px;
}

.window-input-group {
  display: flex;
  align-items: center;
  gap: 10px;
}

.add-window-btn {
  width: 100%;
  margin-top: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  background-color: #f8f9fa;
  border: 1px dashed #dcdfe6;
  border-radius: 4px;
  padding: 8px 0;

  &:hover {
    background-color: #f1f1f1;
    border-color: #c0c4cc;
    color: #409eff;
  }
}

.empty-container {
  height: 400px;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.platform-item {
  padding: 4px 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  height: 100%;

  :deep(.el-divider--horizontal) {
    margin: 8px 0;
    height: 1px;
  }
  .platform-item-image {
    display: flex;
    align-items: center;
  }
}

.account-item {
  display: inline-flex;
  align-items: center;
  border-radius: 4px;
  margin-right: 8px;
  color: #606266;
}

.account-info {
  .account-item {
    display: flex;
    .label {
      color: #606266;
      margin-right: 8px;
      min-width: 70px;
    }
    .value {
      color: #333;
      flex: 1;
    }
  }
}

.global-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.7);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 2000;
  backdrop-filter: blur(3px);
}

.overlay-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  background-color: rgba(255, 255, 255, 0.95);
  padding: 40px 60px;
  border-radius: 12px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
  animation: fadeIn 0.5s ease;
}

.loading-icon {
  font-size: 48px;
  color: #409eff;
  animation: spin 1.5s linear infinite;
  margin-bottom: 24px;
}

.loading-text {
  font-size: 20px;
  font-weight: 600;
  color: #303133;
  margin-bottom: 30px;
}

.stop-button-container {
  margin-top: 10px;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(-20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
</style>

